package myJs

import myJs.myPkg.bootstrap.Bootstrap.default._
import myJs.Utils._
import myJs.Implicits._
import myJs.myPkg._
import myJs.myPkg.jquery._
import org.scalajs.dom.ext.Ajax
import org.scalajs.dom.{FormData, _}
import org.scalajs.dom.raw.HTMLFormElement
import scalatags.Text.TypedTag
import scalatags.Text.all._

import scala.scalajs.js
import scala.scalajs.js.JSON
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import scala.scalajs.js.JSConverters._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.scalajs.js.Dynamic.{global=>g}

/**
 * Created by yz on 2019/4/25
 */
@JSExportTopLevel("UserMetaboDbManage")
object UserMetaboDbManage {

  val updateFormId = "updateForm"
  val updateModalId = "updateModal"

  @JSExport("init")
  def init = {
    initTable
    refreshTable(showLayer = true)
    bootStrapValidator

  }

  val operateColumn = List(
    ColumnOptions.field("operate").title("操作").formatter(operateFmt)
  )

  @JSExport("operateFmt")
  def operateFmt: js.Function = {
    (v: js.Any, row: js.Dictionary[js.Any]) =>
      val updateNameStr = a(title := "修改库名", onclick := s"UserMetaboDbManage.updateNameShow(${JSON.stringify(row)})", cursor.pointer,
        target := "_blank", span(em(cls := "fa fa-edit"))
      )
      val deleteStr = a(
        title := "删除",
        cursor.pointer,
        onclick := s"UserMetaboDbManage.deleteData('" + row("id") + "')",
        target := "_blank",
        span(
          em(cls := "fa fa-close")
        )
      )

      val rs = List(updateNameStr, deleteStr)
      rs.mkString("&nbsp;")
  }

  @JSExport("deleteData")
  def deleteData(id: String) = {
    val options = SwalOptions.title("").text("确定要删除此数据吗？").`type`("warning").showCancelButton(true).
      showConfirmButton(true).confirmButtonClass(Tool.confirmButtonClass).confirmButtonText("确定").closeOnConfirm(false).
      cancelButtonText("取消").showLoaderOnConfirm(true).cancelButtonClass(Tool.cancelButtonClass)
    Swal.swal(options, () => {
      val url = g.jsRoutes.controllers.MetaboDbController.deleteById().url.toString
      Ajax.get(url = s"${url}?id=${id}").map { xhr =>
        refreshTable { () =>
          Swal.swal(SwalOptions.title("成功").text("删除成功").`type`("success"))
        }
      }
    })
  }

  def initTable = {
    val tableId = "table"
    val columnNames = List("dbName", "uploadTime")
    val columnNameMap = Map("dbName" -> "库名", "uploadTime" -> "上传时间")
    val columns = columnNames.map { columnName =>
      val title = columnNameMap.getOrElse(columnName, columnName)
      val fmt = tbFmt(columnName)
      ColumnOptions.field(columnName).title(title).sortable(true).formatter(fmt)
    } ::: operateColumn
    val options = TableOptions.columns(columns.toJSArray)
    $(s"#${tableId}").bootstrapTable(options)
  }

  @JSExport("add")
  def add = {
    val bv = jQuery("#form").data("bootstrapValidator")
    bv.validate()
    val valid = bv.isValid().asInstanceOf[Boolean]
    if (valid) {
      addExec
    }
  }

  @JSExport("updateNameShow")
  def updateNameShow(dict: js.Dictionary[String]) = {
    $("#updateForm input[name='orignalDbName']").`val`(dict("dbName"))
    $("#updateForm input[name='id']").`val`(dict("id"))
    jQuery("#updateModal").modal("show")
  }

  @JSExport("updateName")
  def updateName = {
    val formId = updateFormId
    val modalId = updateModalId
    val bv = jQuery(s"#${formId}").data("bootstrapValidator")
    bv.validate()
    val valid = bv.isValid().asInstanceOf[Boolean]
    if (valid) {
      val data = $(s"#${formId}").serialize()
      val index = layer.alert(Tool.myElement, Tool.layerOptions)
      val url = g.jsRoutes.controllers.MetaboDbController.updateName().url.toString
      val ajaxSettings = JQueryAjaxSettings.url(url).`type`("post").data(data).success { (data, status, e) =>
        refreshTable { () =>
          layer.close(index)
          jQuery(s"#${modalId}").modal("hide")
          bv.resetForm(true)
          Swal.swal(SwalOptions.title("成功").text("修改库名成功!").`type`("success"))
        }
      }
      $.ajax(ajaxSettings)
    }
  }

  def addExec = {
    val formData = new FormData(document.getElementById("form").asInstanceOf[HTMLFormElement])
    val element = div(id := "content",
      span(id := "info", "正在上传数据文件",
        span(id := "progress", "。。。")), " ",
      img(src := "/assets/images/running2.gif", cls := "runningImage", width := 30, height := 20)
    ).render
    val index = layer.alert(element, Tool.layerOptions)
    val url = g.jsRoutes.controllers.MetaboDbController.add().url.toString
    val xhr = new XMLHttpRequest
    xhr.open("post", url)
    xhr.upload.onprogress = progressHandlingFunction
    xhr.onreadystatechange = (e) => {
      if (xhr.readyState == XMLHttpRequest.DONE) {
        val data = xhr.response
        val rs = JSON.parse(data.toString).asInstanceOf[js.Dictionary[String]]
        if (rs.get("error").isEmpty) {
          refreshTable { () =>
            layer.close(index)
            jQuery("#addModal").modal("hide")
            val options = SwalOptions.`type`("success").title("成功!").text("新增库完成!")
            Swal.swal(options)
          }
        } else {
          layer.close(index)
          layer.msg(rs("error"), LayerOptions.icon(5).time(3000))
        }
      }
    }
    xhr.send(formData)

  }

  def refreshTable(f: () => js.Any = () => (), showLayer: Boolean = false) = {
    val index = if (showLayer) layer.alert(Tool.loadingElement, Tool.layerOptions) else 0
    val url = g.jsRoutes.controllers.MetaboDbController.getAllMetaboDb().url.toString
    val ajaxSettings = JQueryAjaxSettings.url(s"${url}").contentType("application/json").
      `type`("get").success { (data, status, e) =>
      $("#table").bootstrapTable("load", data)
      layer.close(index)
      f()
    }
    $.ajax(ajaxSettings)

  }

  def tbFmt(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => columnName match {
    case "dbName" => {
      val detailUrl = g.jsRoutes.controllers.MetaboDbController.detailInfoBefore().url.toString
      a(title := "详情", href := s"${detailUrl}?id=${row("id")}", cursor.pointer, target := "_blank",
        v.toString
      ).render
    }
    case _ => v
  }


  @JSExport("addShow")
  def addShow = {
    jQuery("#addModal").modal("show")
  }

  def bootStrapValidator = {
    formBootStrapValidator
    updateFormBootStrapValidator
  }

  def formBootStrapValidator = {
    val url = g.jsRoutes.controllers.MetaboDbController.nameCheck().url.toString
    val dict = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> js.Dictionary(
        "dbName" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "库名不能为空!"
            ),
            "remote" -> js.Dictionary(
              "message" -> "库名已存在！",
              "url" -> url,
              "delay" -> 1000,
              "type" -> "POST",
            ),
          )
        ),
        "file" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "请选择一个数据文件!"
            ),
            "file" -> js.Dictionary(
              "message" -> "请选择一个Excel(*.xlsx)格式的数据文件!",
              "extension" -> "xlsx",
            ),
          )
        ),
      )
    )
    g.$("#form").bootstrapValidator(dict)
  }

  def updateFormBootStrapValidator = {
    val url = g.jsRoutes.controllers.MetaboDbController.nameCheck().url.toString
    val dict = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> js.Dictionary(
        "dbName" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "库名不能为空!"
            ),
            "remote" -> js.Dictionary(
              "message" -> "库名已存在!",
              "url" -> url,
              "type" -> "POST",
              "delay" -> 1000
            ),
          )
        ),
      )
    )
    g.$("#updateForm").bootstrapValidator(dict)

  }


}
